package com.seh.contentcenter.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.seh.contentcenter.dto.ChatUserDTO;
import com.seh.contentcenter.dto.MsgDTO;
import com.seh.contentcenter.dto.UserDTO;
import com.seh.contentcenter.entity.Msg;
import com.seh.contentcenter.feignclient.UserCenterFeignClient;
import com.seh.contentcenter.mapper.MsgMapper;
import com.seh.contentcenter.service.MsgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class MsgServiceImpl implements MsgService {
    @Autowired
    private MsgMapper msgMapper;
    @Autowired
    private UserCenterFeignClient userCenterFeignClient;
    @Autowired
    private RedisTemplate<String, Object> objectRedisTemplate;

    /**
     * 新增一条单聊消息
     *
     * @param msg
     * @return
     */
    @Cacheable(value = "msgCache", key = "#msg.fromId + '-' + #msg.toId")
    @Override
    public String insertMsg(Msg msg) {
        int result = msgMapper.insert(msg);
        if (result > 0) {
            // 删除对应的缓存条目
            objectRedisTemplate.delete("msgCache");
            return "添加成功";
        }
        return "添加失败";
    }

    /**
     * 新增一条图片消息
     *
     * @param msg
     * @return
     */
    @Cacheable(value = "msgCache", key = "#msg.fromId + '-' + #msg.toId")
    @Override
    public String insertImgMsg(Msg msg) {
        int result = msgMapper.insert(msg);
        if (result > 0) {
            // 删除对应的缓存条目
            objectRedisTemplate.delete("msgCache");
            return "添加成功";
        }
        return "添加失败";
    }

    /**
     * 查询当前用户聊天列表
     *
     * @param userId 用户ID
     * @return 聊天消息列表
     */
    @Cacheable(value = "msgCache", key = "#msg.fromId + '-' + #msg.toId")
    @Override
    public List<MsgDTO> getMsgList(Integer userId) {
        // 检查缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("msgCache", userId.toString());
        if (hasKey) {
            // 从缓存中获取数据
            List<Msg> msgList = JSONObject.parseArray(objectRedisTemplate.opsForHash().get("msgCache", userId.toString()).toString(), Msg.class);
            List<MsgDTO> msgDTOList = new ArrayList<>();
            for (Msg msg : msgList) {
                MsgDTO msgDTO = new MsgDTO();
                BeanUtil.copyProperties(msg, msgDTO);
                msgDTOList.add(msgDTO);
            }
            return msgDTOList;
        }

        // 从数据库中查询聊天消息列表
        QueryWrapper<Msg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("from_id", userId).ne("to_id", userId)
                .or()
                .eq("to_id", userId).ne("from_id", userId)
                .orderByDesc("send_time");
        List<Msg> msgList = msgMapper.selectList(queryWrapper);
        List<MsgDTO> msgDTOList = new ArrayList<>();
        for (Msg msg : msgList) {
            MsgDTO msgDTO = new MsgDTO();
            BeanUtil.copyProperties(msg, msgDTO);
            msgDTOList.add(msgDTO);
        }

        // 将数据存入缓存
        objectRedisTemplate.opsForHash().put("msgCache", userId.toString(), JSONUtil.toJsonStr(msgList));

        return msgDTOList;
    }

    /**
     * 查询聊天详情
     *
     * @param fromId 发送者ID
     * @param toId   接收者ID
     * @return 聊天消息详情列表
     */
    @Cacheable(value = "msgCache", key = "#fromId + '-' + #toId")
    @Override
    public List<MsgDTO> getMsgDetail(Integer fromId, Integer toId) {
        // 检查缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("msgCache", fromId + "-" + toId);
        if (hasKey) {
            // 从缓存中获取数据
            List<Msg> msgList = JSONObject.parseArray(objectRedisTemplate.opsForHash().get("msgCache", fromId + "-" + toId).toString(), Msg.class);
            List<MsgDTO> msgDTOList = new ArrayList<>();
            for (Msg msg : msgList) {
                MsgDTO msgDTO = new MsgDTO();
                BeanUtil.copyProperties(msg, msgDTO);
                msgDTOList.add(msgDTO);
            }
            return msgDTOList;
        }

        // 从数据库中查询聊天消息详情列表
        QueryWrapper<Msg> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper.eq("from_id", fromId).eq("to_id", toId))
                .or(wrapper -> wrapper.eq("from_id", toId).eq("to_id", fromId))
                .orderByAsc("send_time");
        List<Msg> msgList = msgMapper.selectList(queryWrapper);
        List<MsgDTO> msgDTOList = new ArrayList<>();
        for (Msg msg : msgList) {
            MsgDTO msgDTO = new MsgDTO();
            BeanUtil.copyProperties(msg, msgDTO);
            msgDTOList.add(msgDTO);
        }

        // 将数据存入缓存

        objectRedisTemplate.opsForHash().put("msgCache", fromId + "-" + toId, JSONUtil.toJsonStr(msgList));

        return msgDTOList;
    }

    /**
     * 查询当前用户聊天对象（不允许有重复元素使用HashSet）
     *
     * @param userId
     * @return
     */
    @Override
    public List<UserDTO> getUserDTO(Integer userId) {

        List<MsgDTO> msgDTOList = getMsgList(userId);

        Set<UserDTO> uniqueUsers = new HashSet<>();

        for (MsgDTO msgDTO : msgDTOList) {
            if (!msgDTO.getToId().equals(userId)) {
                Integer toId = msgDTO.getToId();
                UserDTO toUser = userCenterFeignClient.findUserInfoById(toId);
                uniqueUsers.add(toUser);
            } else if (!msgDTO.getFromId().equals(userId)) {
                Integer fromId = msgDTO.getFromId();
                UserDTO fromUser = userCenterFeignClient.findUserInfoById(fromId);
                uniqueUsers.add(fromUser);
            }
        }
        return new ArrayList<>(uniqueUsers);
    }

    /**
     * 查询当前用户聊天对象列表（带最后一条回复和日期）
     *
     * @param userId 当前用户ID
     * @return 聊天用户DTO列表
     */
    @Cacheable(value = "msgCache", key = "#msg.fromId + '-' + #msg.toId")
    @Override
    public List<ChatUserDTO> getUserDTOWithLastMsg(Integer userId) {
        // 检查缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("msgCache", userId.toString());
        if (hasKey) {
            // 从缓存中获取数据
            List<ChatUserDTO> chatUserDTOList = JSONObject.parseArray(objectRedisTemplate.opsForHash().get("msgCache", userId.toString()).toString(), ChatUserDTO.class);
            return chatUserDTOList;
        }

        // 查询当前用户聊天对象
        List<UserDTO> userDTOList = getUserDTO(userId);

        List<ChatUserDTO> chatUserDTOList = new ArrayList<>();
        for (UserDTO userDTO : userDTOList) {
            Integer userId1 = userDTO.getUserId();
            // 查询当前用户与聊天对象之间的聊天详情
            List<MsgDTO> msgDTOList = getMsgDetail(userId, userId1);
            String lastMessage = "";
            String lastTime = "";
            if (!msgDTOList.isEmpty()) {
                // 获取聊天列表最后一条消息
                MsgDTO lastMsg = msgDTOList.get(msgDTOList.size() - 1);
                lastMessage = lastMsg.getMessage();
                lastTime = lastMsg.getSendTime();
            }
            ChatUserDTO chatUserDTO = new ChatUserDTO();
            chatUserDTO.setUserDTO(userDTO);
            chatUserDTO.setLastMessage(lastMessage);
            chatUserDTO.setLastSendTime(lastTime);
            chatUserDTOList.add(chatUserDTO);
        }

        // 将数据存入缓存
        objectRedisTemplate.opsForHash().put("msgCache", userId.toString(), JSONUtil.toJsonStr(chatUserDTOList));

        return chatUserDTOList;
    }
}
